package com.example.clicker;


import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class Buflire <T> implements OnTouchListener,OnLongClickListener {
	
	public static final  int  BUTTON_TYPE=1;
	public static final  int  FRAME_LAYOUT_TYPE=2;
	public static final  int  LINEAR_LAYOUT_VERTICAL_TYPE=3;
	public static final  int  LINEAR_LAYOUT_HORIZONTAL_TYPE=4;
	public static final  int  RELATIVE_LAYOUT_TYPE=5;
	
	
		// Счетчик числа дочерних элементов, размеры элемента, 
	// переменная хранения ресурса нажатой и ненажатой оболасти
	int childcounter;
	int bnormal;
	int bpressed;
	int bwidth;
	int bheight;
	int mGravity;
	
	Button vbtn;
	private T o;
		// Координаты первого нажатия, изменения размера,диагональ статус каждой границы и статус углов 
	int type_buflire;
	float xff,yff;
	int dxsize,dysize;
	float maxr;
	boolean cornerdrag;
	boolean l,r,t,b;
	// Статус выбора кнопки при длинном нажатии
	boolean bsel;
	
	public Buflire(ContextThemeWrapper Context, int normal,int selected,int type) {
		// TODO Auto-generated constructor stub
		childcounter=0;
		l=r=t=b=false;
		bnormal=normal;
		bpressed=selected;
		type_buflire=type;
		
		switch(type)
		{
		case 1:
			o = (T) new Button(Context);
			vbtn=(Button)o;
			vbtn.setText("Button");
		break;
		case 2:
			o=(T) new FrameLayout(Context);
			vbtn=new Button(Context);
			vbtn.setText("Frame Button");
		break;
		case 3:
		case 4:
			o=(T) new LinearLayout(Context);
			vbtn=new Button(Context);
			vbtn.setText("LinearLayout Button");
		break;
		case 5:
			o = (T) new RelativeLayout(Context);
			vbtn=new Button(Context);
			vbtn.setText("RelativeLayout Button");
		break;
			
		}
		
		SetLayer(vbtn,R.id.lred,0);
		SetLayer(vbtn,R.id.rred,0);
		SetLayer(vbtn,R.id.tred,0);
		SetLayer(vbtn,R.id.bred,0);
		
		//vbtn.setBackgroundResource(bnormal);
	}
	OnLongClickListener GetOnLongClick()
	{
		return this;
	}
	OnTouchListener GetOnTouch()
	{
		return this;
	}
	public boolean Add(Buflire ...bbf)
	{
			
		for(Buflire bf:bbf)
		{
			// Не можем добавить себя же
			if(this==bf)
				return false;
			
			switch(this.type_buflire)
			{
			// Нельзя добавить что-либо к кнопке
			case 1:
				return false;
			case 2:
				// Проверяем объект на наличие
				for(int i=0;i<((FrameLayout)o).getChildCount();i++)
					if((View)((FrameLayout)o).getChildAt(i)==(View)bf.o)
						return false;
				// Если такого нет добавляем
				((FrameLayout)o).addView((View)bf.o);
				break;
			case 3:
			case 4:
				for(int i=0;i<((LinearLayout)o).getChildCount();i++)
					if((View)((LinearLayout)o).getChildAt(i)==(View)bf.o)
						return false;
				((LinearLayout)o).addView((View)bf.o);
			break;
			case 5:
				for(int i=0;i<((LinearLayout)o).getChildCount();i++)
					if((View)((LinearLayout)o).getChildAt(i)==(View)bf.o)
						return false;
				((LinearLayout)o).addView((View)bf.o);
			break;
				
			}
		childcounter++;
		}
		return true;
	}
	public boolean Remove(Buflire... bbf)
	{
		View v=vbtn;
		for(Buflire bf:bbf)
		{
		if(o instanceof Button)
			return false;
		if(o instanceof LinearLayout)
			if( ((LinearLayout)o).getChildCount()>0 )
			{
				((View)bf.o).setVisibility(View.GONE);
				((LinearLayout)o).removeView((View)bf.o);
				childcounter--;
					if(childcounter==0)
						SetLayer(v,(type_buflire==LINEAR_LAYOUT_VERTICAL_TYPE)?
											R.id.linearv:R.id.linearlh,255);
			}
				
		if(o instanceof FrameLayout)
			if( ((FrameLayout)o).getChildCount()>0 )
			{
				((View)bf.o).setVisibility(View.GONE);
				((FrameLayout)o).removeView((View)bf.o);
				childcounter--;
					if(childcounter==0)
						SetLayer(v,R.id.main_image,255);
			}
			
		if(o instanceof RelativeLayout)
			if( ((RelativeLayout)o).getChildCount()>0 )
			{
				((View)bf.o).setVisibility(View.GONE);
				((RelativeLayout)o).removeView((View)bf.o);
				childcounter--;
					if(childcounter==0)
						SetLayer(v,R.id.relative,255);
			}
		}
		return true;
	}

public boolean SetLayoutParams(ViewGroup.LayoutParams prms){

	if(prms!=null)
		return true;
	int tGravity=0;
	if(l)
		tGravity = tGravity | Gravity.START;
	if(r)
		tGravity = tGravity | Gravity.END;
	if(t)
		tGravity = tGravity | Gravity.TOP;
	if(b)
		tGravity = tGravity | Gravity.BOTTOM;
	mGravity=tGravity;

	if(o instanceof FrameLayout || o instanceof LinearLayout)
	{
		FrameLayout.LayoutParams paramf=new FrameLayout.LayoutParams(null,null) ;
		if(paramf==null)
			return false;
		paramf.height=bheight;
		paramf.width=bwidth;
		paramf.gravity=mGravity;
		if(l && r)
			paramf.width=LayoutParams.MATCH_PARENT;
		if(t && b)
			paramf.height=LayoutParams.MATCH_PARENT;

		((FrameLayout)getO()).setLayoutParams(paramf);
	    return true;
	} else
	{
		LayoutParams params=new LayoutParams(null,null) ;
		if(params==null)
			return false;
		params.height=bheight;
		params.width=bwidth;
		if(l && r)
			params.width=LayoutParams.MATCH_PARENT;
		if(t && b)
			params.height=LayoutParams.MATCH_PARENT;

		((View)getO()).setLayoutParams(params);
	
	}
	
	return true;
}
public boolean SetSize(View v,int sx,int sy){
	ViewGroup.LayoutParams lp=v.getLayoutParams();
	lp.height=bheight;
	lp.width=bwidth;
	v.setLayoutParams(lp);
	return true;
}

/**
 * @return the o
 */
public T getO() {
	return o;
}
/**
 * @param o the o to set
 */
private void setO(T o) {
	this.o = o;
}
boolean SetLayer(View v,int layer,int alpha)
{
	LayerDrawable ld = ((LayerDrawable)v.getResources().getDrawable(bpressed));
	if(ld==null)
		return false;
	
	Drawable dl=ld.findDrawableByLayerId(layer);
	if(dl==null)
		return false;
	dl.setAlpha(alpha);
	//vbtn.setBackgroundResource(bpressed);
	return true;
}
	
	@Override
	public boolean onLongClick(View v) {
		// TODO Auto-generated method stub
		bwidth=vbtn.getWidth();
		bheight=vbtn.getHeight();
		maxr=(float)Math.sqrt(bwidth*bwidth+bheight*bheight)/2;
		bsel=true;
		v.setBackgroundResource(bpressed);
		  return true;
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		// Событие
		int actionMask = event.getActionMasked();
		float w=v.getWidth();
		float h=v.getHeight();
	
		int deltax=(int)(w/5);
		int deltay=(int)(h/5);
	
		
		// Число Касаний
		//int pointCount = event.getPointerCount();
		switch(actionMask)
		{
		case MotionEvent.ACTION_DOWN:
			
			xff=event.getX(0);
			yff=event.getY(0);
				break;
		case MotionEvent.ACTION_UP:
			
			if(bsel)
			{
		
				//SetSize(bwidth+dxsize, bheight+dysize);
				v.setBackgroundResource(bnormal);
				bsel=false;
			}
			
			break;
		// Последующие нажатия
		case MotionEvent.ACTION_POINTER_DOWN:
	
			if(bsel)
			{
				float x=event.getX(1);
				float y=event.getY(1);
				float xsf=x;
				float ysf=y;
				float modwx=((x-w)>0)?(x-w):(w-x);
				float modhy=((y-h)>0)?(y-w):(w-y);
				float modx=(x>0)?x:-x;
				float mody=(y>0)?y:-y;
				
				if(modx<deltax && y>deltay && y<(h-deltay))
				{
				l=!l;
				SetLayer(v,R.id.lred,((l)?255:0));
				}
				if(modwx<deltax && y>deltay && y<(h-deltay))
				{
				r=!r;
				SetLayer(v,R.id.rred,((r)?255:0));
				}
				if(mody<deltay && x>deltax && x<(w-deltax))
				{
				t=!t;
				SetLayer(v,R.id.tred,((t)?255:0));
					}
				if(modhy<deltay && x>deltax && x<(w-deltax))
				{
				b=!b;
				SetLayer(v,R.id.bred,((b)?255:0));
				}
		
				if(y>(yff-deltay) && y<(yff+deltay) && (x>(xff+deltax) || x<(xff-deltax)))
					dxsize+=(x<xff)?-5:5;
										
				if(x>(xff-deltax) && x<(xff+deltax) && (y>(yff+deltay) || y<(yff-deltay)))
					dysize+=(y<yff)?-5:5;

				SetSize(v,bwidth+dxsize, bheight+dysize);
				
			    cornerdrag=
						// Правый нижний угол
						xsf>(w-deltax) && xsf<(w+deltax) && ysf>(h-deltay) && ysf<(h+deltay) ||
						// Левый нижний угол
						xsf>-deltax && xsf<deltax && ysf>(h-deltay) && ysf<(h+deltay) ||
						// Правый верхний угол
						xsf>(w-deltax) && xsf<(w+deltax) && ysf>(-deltay) && ysf<(deltay) ||
						// Левый верхний Угол
						xsf>(-deltax) && xsf<(deltax) && ysf>(-deltay) && ysf<(+deltay);
			v.setBackgroundResource(bpressed);
			v.refreshDrawableState();
			}					
			break;
		// Последующие отпускания	
		case  MotionEvent.ACTION_POINTER_UP:
			cornerdrag=false;
			break;
		// Перемещение
		case MotionEvent.ACTION_MOVE:

					if(cornerdrag && event.getPointerCount()==2)
				{
						float mx=event.getX(1);
						float my=event.getY(1);
						
						float xq=(xff<mx)?(xff-mx)*(xff-mx):(mx-xff)*(mx-xff);
						float yq=(yff<my)?(yff-my)*(yff-my):(my-yff)*(my-yff);
						float dr=(float) Math.sqrt(xq+yq);
			
					if(v.getParent() instanceof LinearLayout)
				    {
					    	
					    	LinearLayout.LayoutParams param = (LinearLayout.LayoutParams)(v.getLayoutParams());
					    	param.weight =dr/maxr;
					    	v.setLayoutParams(param);
				    	
				   	v.refreshDrawableState(); // This is to explicit force the refresh.
				     }
						
				}
				  	
			break;
			
		}
		return false;
	}

}
